﻿#include "mp4_pkt.h"
#include "mov-buffer.h"

const struct mov_buffer_t* mov_file_buffer(void);
#include <stdio.h>

#if defined(_WIN32) || defined(_WIN64)
#define fseek64 _fseeki64
#define ftell64 _ftelli64
#elif defined(OS_LINUX)
#define fseek64 fseeko64
#define ftell64 ftello64
#else
#define fseek64 fseek
#define ftell64 ftell
#endif

static int mov_file_read(void* fp, void* data, uint64_t bytes)
{
    if (bytes == fread(data, 1, bytes, (FILE*)fp))
        return 0;
	return 0 != ferror((FILE*)fp) ? ferror((FILE*)fp) : -1 /*EOF*/;
}

static int mov_file_write(void* fp, const void* data, uint64_t bytes)
{
	return bytes == fwrite(data, 1, bytes, (FILE*)fp) ? 0 : ferror((FILE*)fp);
}

static int mov_file_seek(void* fp, uint64_t offset)
{
	return fseek64((FILE*)fp, offset, SEEK_SET);
}

static uint64_t mov_file_tell(void* fp)
{
	return ftell64((FILE*)fp);
}

const struct mov_buffer_t* mov_file_buffer(void)
{
	static struct mov_buffer_t s_io = {
		mov_file_read,
		mov_file_write,
		mov_file_seek,
		mov_file_tell,
	};
	return &s_io;
}

int init_av_track(struct mov_h264_test_t* ctx, int codec_type, unsigned char* s_extra_data)
{
	int extra_data_size = 0;
	if (ctx->track < 0)
	{
		if (codec_type == 0)
		{//H264 �ȴ� SPS��PPS �ķ��� 
			if (ctx->avc.nb_sps < 1 || ctx->avc.nb_pps < 1)
			{
				//ctx->ptr = end;
				return 0; // waiting for sps/pps
			}
		}
		else if (codec_type == 1)
		{//H265 �ȴ�SPS��PPS�ķ��� 
			if (ctx->hevc.numOfArrays < 1)
			{
				//ctx->ptr = end;
				return 0; // waiting for vps/sps/pps
			}
		}

		if (codec_type == 0)
			extra_data_size = mpeg4_avc_decoder_configuration_record_save(&ctx->avc, s_extra_data, 64 << 10);
		else if (codec_type == 1)
			extra_data_size = mpeg4_hevc_decoder_configuration_record_save(&ctx->hevc, s_extra_data, 64 << 10);

		if (extra_data_size <= 0)
		{
			// invalid AVCC
			return 0;
		}

		// TODO: waiting for key frame ???
		if (codec_type == 0)
			ctx->track = mov_writer_add_video(ctx->mov, MOV_OBJECT_H264, ctx->width, ctx->height, s_extra_data, extra_data_size);
		else if (codec_type == 1)
			ctx->track = mov_writer_add_video(ctx->mov, MOV_OBJECT_HEVC,ctx->width, ctx->height, s_extra_data, extra_data_size);

		if (ctx->track < 0)
			return 0;
	}                                         
	return 1;
}
